#include "EventExecuter.h"

#include "EventList.h"
#include "EventNode.h"
#include "EventObject.h"
#include "NetworkObject.h"

#include <libintl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define _(String) gettext(String)
/**
 * 数据管理器，需要连接使用
 */
static DataManager *data_manager = NULL;
/**
 * 网络对象，需要连接使用
 */
static NetworkObject *net_obj = NULL;

struct _EventExecuter
{
	EventObject parent_instance;

	/* 执行命令的包装队列 */
	ExecuteQueue  *exe_queue;
	ExecuteQueue **q_end;

	/* 是否正在执行指令 */
	bool is_executing;

	/* 队列是否已上锁 */
	bool is_queuing;
};

static void
event_executer_finalize(EventExecuter *self)
{
	/* 等待任务完毕后再执行析构 */
	while (self->is_executing)
		;
	event_object_unref(self->exe_queue);
	event_object_unref(data_manager);
	event_object_unref(net_obj);
}

EventExecuter *
event_executer_new(void)
{
	EventExecuter *object = MALLOC_NEW(EventExecuter);

	event_object_init(EVENT_OBJECT(object));
	event_object_set_finalize(object, FINALIZE(event_executer_finalize));

	object->exe_queue    = NULL;
	object->is_executing = false;
	object->is_queuing   = false;

	return object;
}

void
event_executer_connect_data_manager(EventExecuter *self,
				    DataManager	  *_data_manager)
{
	return_if_fail(self != NULL && _data_manager != NULL,
		       event_executer_connect_data_manager);
	data_manager = EO_REF(_data_manager, DataManager);
}

void
event_executer_connect_network_object(EventExecuter *self,
				      NetworkObject *_net_obj)
{
	return_if_fail(self != NULL && _net_obj != NULL,
		       event_executer_connect_network_object);
	net_obj = EO_REF(_net_obj, NetworkObject);
}

/**
 * 生成一个 ServerResponse 节点，指示服务器关闭该 socket 。
 * 该 ExecuteQueue 节点为空
 */
static ExecuteQueue *
close_node_function_create(int sock)
{
	EventList *cmd = event_list_new();
	event_list_add_data(cmd, EPTR((euint64)NETWORK_RET_TYPE_CLOSE),
			    EVENT_TYPE_INT32, NULL);
	ExecuteQueue *q_node = execute_queue_new();
	execute_queue_set(q_node, sock, cmd);
	return q_node;
}

/**
 * 全局变量：ServerResponse 的基础节点。
 */
static ExecuteQueue *send_node;
/**
 * 全局变量：ServerResponse 的指令，可序列化处理后发送。
 */
static EventList *send_list;
/**
 * 全局变量：用户电话号码
 */
static euint64 phone;
/**
 * 全局变量：用户 UserID
 */
static euint32 user_id;
/**
 * 全局变量：数据管理器的处理返回值
 */
static DataManagerRet dm_ret;
/**
 * 全局变量：ServerResponse 返回类型
 */
static ResponseType re_type;

/**
 * 关闭连接的方法。若处理出现错误，服务器可不返回任何信息，直接关闭连接。
 */
static ExecuteQueue *
close_connect(euint64 online_id, EventList *args, int sock)
{
	return close_node_function_create(sock);
}

/**
 * 用户注册，参数有三个
 * 1. 电话号码，2. 用户名，3. 密码
 */
static ExecuteQueue *
register_method(euint64 online_id, EventList *args, int sock)
{
	EventString *user_name, *password;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_logon, "用户注册。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT64))
		goto return_with_node;
	phone = EN_GET_D(args, euint64);
	args  = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	user_name = EN_GET_D(args, EventString *);
	args	  = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	password = EN_GET_D(args, EventString *);

	/* 用户不存在于本地，注册用户 */
	dm_ret =
		data_manager_register(data_manager, phone, user_name, password);
	if (dm_ret == DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SUCCESS;
	else if (dm_ret == DATA_MANAGER_USER_ALREADY_EXISTS_ERROR)
		re_type = RESPONSE_TYPE_USER_EXISTED;
	else
		re_type = RESPONSE_TYPE_ERROR;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 用户无验证码登陆，参数有两个：
 * 1. 电话号码，2. 用户密码
 */
static ExecuteQueue *
user_logon(euint64 online_id, EventList *args, int sock)
{
	EventString *password, *user_name = NULL;
	int	     status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_logon, "用户无验证码登陆。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT64))
		goto return_with_node;
	phone = EN_GET_D(args, euint64);
	args  = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	password = EN_GET_D(args, EventString *);
	/* 验证用户是否存在 */
	dm_ret = data_manager_verify_user(data_manager, phone, password);
	if (dm_ret == DATA_MANAGER_SUCCESS) {
		status = data_manager_verify_logon_state(data_manager,
							 online_id);
		if (status == 2) {
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		} else {
			status	= data_manager_flush_online_state(data_manager,
								  online_id);
			re_type = (status == 0 ? RESPONSE_TYPE_SUCCESS :
						 RESPONSE_TYPE_ERROR);
		}
	} else {
		if (dm_ret == DATA_MANAGER_USER_NOT_REGISTER_ERROR)
			re_type = RESPONSE_TYPE_USER_NOT_EXISTED;
		else if (dm_ret == DATA_MANAGER_USER_VERIFY_FAILED)
			re_type = RESPONSE_TYPE_VERIFY_PASSWORD_FAILED;
		else
			re_type = RESPONSE_TYPE_ERROR;
		goto return_with_node;
	}

	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	if (re_type == RESPONSE_TYPE_SUCCESS)
		user_name = data_manager_dup_user_name(data_manager, user_id);

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (user_name) {
		event_list_add_data(send_list, user_name, EVENT_TYPE_STRING,
				    event_object_unref);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 用户带验证码登陆，参数：
 * 1. 电话号码，2. 密码，3. 验证码
 *
 * 目前尚未使用验证码相关 SDK，默认验证码为 6666
 */
static ExecuteQueue *
user_logon_with_verification_code(euint64 online_id, EventList *args, int sock)
{
	EventString *password, *user_name = NULL;
	eint32	     verification_code;
	const eint32 default_vcode = 6666;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_logon_with_verification_code,
		    "用户带验证码登陆。");
#endif

	re_type	  = RESPONSE_TYPE_ERROR;
	online_id = 0;
	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT64))
		goto return_with_node;
	phone = EN_GET_D(args, euint64);
	args  = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	password = EN_GET_D(args, EventString *);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_INT32))
		goto return_with_node;
	verification_code = (euint32)EN_GET_D(args, eint64);
	/* 验证用户电话和密码是否正确 */
	dm_ret = data_manager_verify_user(data_manager, phone, password);
	if (dm_ret == DATA_MANAGER_SUCCESS &&
	    verification_code == default_vcode) {
		/* 更新 onlineID */
		user_id = data_manager_get_uid_from_phone(data_manager, phone);
		online_id = data_manager_add_keep_item(data_manager, user_id);
		if (online_id != 0)
			re_type = RESPONSE_TYPE_RETURN_VERIFY_CODE;
		else
			re_type = RESPONSE_TYPE_ERROR;
	} else {
		if (dm_ret == DATA_MANAGER_USER_VERIFY_FAILED)
			re_type = RESPONSE_TYPE_VERIFY_PASSWORD_FAILED;
		else if (dm_ret == DATA_MANAGER_USER_NOT_REGISTER_ERROR)
			re_type = RESPONSE_TYPE_USER_NOT_EXISTED;
		else
			re_type = RESPONSE_TYPE_ERROR;
	}

	if (re_type == RESPONSE_TYPE_RETURN_VERIFY_CODE)
		user_name = data_manager_dup_user_name(data_manager, user_id);

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (re_type == RESPONSE_TYPE_RETURN_VERIFY_CODE) {
		event_list_add_data(send_list, EPTR(online_id),
				    EVENT_TYPE_UINT64, NULL);
	}
	if (user_name) {
		event_list_add_data(send_list, user_name, EVENT_TYPE_STRING,
				    event_object_unref);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改用户密码。参数：
 * 1. 原密码，2. 新密码
 */
static ExecuteQueue *
modify_password(euint64 online_id, EventList *args, int sock)
{
	EventString *old_password, *new_password;
	int	     status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_password, "修改用户密码。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	status	= data_manager_verify_logon_state(data_manager, online_id);
	if (status == 1) {
		re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	} else if (status == 2) {
		re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		goto return_with_node;
	}
	if (!event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	old_password = EN_GET_D(args, EventString *);
	args	     = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	new_password = EN_GET_D(args, EventString *);
	user_id	     = data_manager_get_uid_from_oid(data_manager, online_id);
	phone	     = data_manager_get_phone_from_uid(data_manager, user_id);
	status = data_manager_verify_user(data_manager, phone, old_password);
	if (status != DATA_MANAGER_SUCCESS) {
		re_type = RESPONSE_TYPE_VERIFY_PASSWORD_FAILED;
		goto return_with_node;
	}
	status = data_manager_modify_user_password(data_manager, user_id,
						   new_password);
	if (status != DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SYSTEM_BUGS;
	else
		re_type = RESPONSE_TYPE_SUCCESS;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改用户名，参数：
 * 1. 新用户名
 */
static ExecuteQueue *
modify_user_name(euint64 online_id, EventList *args, int sock)
{
	EventString *user_name;
	int	     status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_user_name, "修改用户名。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	user_name = EN_GET_D(args, EventString *);
	status	  = data_manager_verify_logon_state(data_manager, online_id);
	if (status == 2) {
		re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		goto return_with_node;
	} else if (status == 1) {
		re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status =
		data_manager_modify_user_name(data_manager, user_id, user_name);
	if (status != DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_ERROR;
	else
		re_type = RESPONSE_TYPE_SUCCESS;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改事件组名，参数：
 * 1. GroupID，2. 事件组名
 */
static ExecuteQueue *
modify_group_name(euint64 online_id, EventList *args, int sock)
{
	EventString *group_name;
	euint32	     group_id;
	int	     status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_group_name, "修改事件组名。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING)) {
		re_type = RESPONSE_TYPE_ERROR;
		goto return_with_node;
	}
	group_name = EN_GET_D(args, EventString *);
	//
	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status == 2) {
		re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		goto return_with_node;
	} else if (status == 1) {
		re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status = data_manager_modify_group_name(data_manager, user_id, group_id,
						group_name);
	if (status == DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SUCCESS;
	else if (status == DATA_MANAGER_GROUP_PERMISSION_DENIED)
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
	else
		re_type = RESPONSE_TYPE_ERROR;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改事件条目，参数：
 * 1. GroupID，2. 事件 EventID，3. 事件截止时间，4. 事件名，5. 事件描述
 */
static ExecuteQueue *
modify_event_item(euint64 online_id, EventList *args, int sock)
{
	EventString *event_name, *event_describe;
	time_t	     end_time;
	euint32	     group_id, event_id;
	int	     status;
	bool	     is_important;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_event_item, "修改事件条目。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	status	= data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	/* 传入参数检查 */
	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	event_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_INT64))
		goto return_with_node;
	end_time = EN_GET_D(args, eint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	event_name = EN_GET_D(args, EventString *);
	args	   = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	event_describe = EN_GET_D(args, EventString *);
	args	       = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	is_important = (bool)EN_GET_D(args, euint64);
	//
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status = data_manager_modify_event_item(data_manager, user_id, group_id,
						event_id, end_time, event_name,
						event_describe, is_important);
	switch (status) {
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_GLOBAL_CAN_NOT_WRITE:
		re_type = RESPONSE_TYPE_GROUP_GLOBAL_CAN_NOT_WRITE;
		break;
	case DATA_MANAGER_GROUP_CAN_NOT_WRITE:
		re_type = RESPONSE_TYPE_GROUP_CAN_NOT_WRITE;
		break;
	case DATA_MANAGER_EVENT_TABLE_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_EVENT_TABLE_NOT_EXIST;
		break;
	case DATA_MANAGER_EVENT_ITEM_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_EVENT_ITEM_NOT_EXIST;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改事件组的总可写标志，参数：
 * 1. GroupID，2. bool 是否可写
 */
static ExecuteQueue *
modify_group_can_write_flag(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id;
	int	status;
	bool	can_write;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_group_can_write_flag,
		    "修改事件组的总可写标志。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	can_write = (bool)EN_GET_D(args, euint64);
	//
	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status = data_manager_modify_group_can_write_flag(data_manager, user_id,
							  group_id, can_write);
	if (status == DATA_MANAGER_GROUP_PERMISSION_DENIED)
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
	else if (status == DATA_MANAGER_GROUP_NOT_EXIST_ERROR)
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
	else if (status == DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SUCCESS;
	else
		re_type = RESPONSE_TYPE_ERROR;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改事件组内用户的可写标志，参数：
 * 1. GroupID，2. UserID，3. bool 是否可写
 */
static ExecuteQueue *
modify_member_can_write_flag(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id, modify_uid;
	int	status;
	bool	can_write;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_member_can_write_flag,
		    "修改事件组内用户的可写标志。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	modify_uid = (euint32)EN_GET_D(args, euint64);
	args	   = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	can_write = (bool)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_modify_member_can_write_flag(
		 data_manager, user_id, group_id, modify_uid, can_write);

	if (status == DATA_MANAGER_GROUP_PERMISSION_DENIED)
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
	else if (status == DATA_MANAGER_GROUP_NOT_EXIST_ERROR)
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
	else if (status == DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SUCCESS;
	else
		re_type = RESPONSE_TYPE_ERROR;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 修改事件组可加入标志，参数：
 * 1. GroupID，2. bool 是否可加入
 */
static ExecuteQueue *
modify_group_can_join_flag(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id;
	int	status;
	bool	can_join;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, modify_group_can_join_flag,
		    "修改事件组可加入标志。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	can_join = (bool)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_modify_group_can_join_flag(data_manager, user_id,
							  group_id, can_join);

	if (status == DATA_MANAGER_GROUP_PERMISSION_DENIED)
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
	else if (status == DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SUCCESS;
	else
		re_type = RESPONSE_TYPE_ERROR;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 创建事件组，参数：
 * 1. 事件组名称，2. 是否可写，3. 是否可加入
 */
static ExecuteQueue *
create_group(euint64 online_id, EventList *args, int sock)
{
	EventString *group_name;
	euint32	     group_id;
	int	     status;
	bool	     global_can_write, can_join, is_success = false;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, create_group, "创建事件组。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	group_name = EN_GET_D(args, EventString *);
	args	   = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	global_can_write = (bool)EN_GET_D(args, euint64);
	args		 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	can_join = (bool)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}

	user_id	 = data_manager_get_uid_from_oid(data_manager, online_id);
	status	 = data_manager_create_group(data_manager, user_id, group_name,
					     global_can_write, can_join);
	group_id = (euint32)status;
	if (status == DATA_MANAGER_NULL_OBJECT_ERROR) {
		re_type = RESPONSE_TYPE_ERROR;
	} else if (status == DATA_MANAGER_USER_NOT_REGISTER_ERROR) {
		re_type = RESPONSE_TYPE_USER_NOT_EXISTED;
	} else if (status > DATA_MANAGER_END) {
		re_type	   = RESPONSE_TYPE_SUCCESS;
		is_success = true;
	} else {
		re_type = RESPONSE_TYPE_SYSTEM_BUGS;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (is_success) {
		event_list_add_data(send_list, EPTR((euint64)group_id),
				    EVENT_TYPE_UINT32, NULL);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 创建新的事件条目，参数：
 * 1. 事件组 GroupID，2. 截止时间，3. 事件名称，4. 事件描述
 */
static ExecuteQueue *
create_event(euint64 online_id, EventList *args, int sock)
{
	EventString *event_name, *event_describe;
	time_t	     end_time;
	euint32	     event_id, group_id;
	int	     status;
	bool	     is_success = false, is_important;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, create_event, "创建新的事件条目。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_INT64))
		goto return_with_node;
	end_time = EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	event_name = EN_GET_D(args, EventString *);
	args	   = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_STRING))
		goto return_with_node;
	event_describe = EN_GET_D(args, EventString *);
	args	       = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT8))
		goto return_with_node;
	is_important = (bool)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_create_event(data_manager, user_id, group_id,
					    end_time, event_name, event_describe,
					    is_important);
	switch (status) {
	case DATA_MANAGER_NULL_OBJECT_ERROR:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_GLOBAL_CAN_NOT_WRITE:
		re_type = RESPONSE_TYPE_GROUP_GLOBAL_CAN_NOT_WRITE;
		break;
	case DATA_MANAGER_GROUP_CAN_NOT_WRITE:
		re_type = RESPONSE_TYPE_GROUP_CAN_NOT_WRITE;
		break;
	default:
		re_type	   = RESPONSE_TYPE_SUCCESS;
		is_success = true;
		event_id   = (euint32)status;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (is_success) {
		event_list_add_data(send_list, EPTR((euint64)event_id),
				    EVENT_TYPE_UINT32, NULL);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 添加用户到事件组，参数：
 * 1. 事件组 GroupID，2. 被添加的用户 UserID
 */
static ExecuteQueue *
add_user_to_group(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id, addtion_uid;
	int	status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, add_user_to_group, "添加用户到事件组。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	addtion_uid = (euint32)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}

	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_add_user_to_group(data_manager, user_id,
						 addtion_uid, group_id);
	switch (status) {
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_PERMISSION_DENIED:
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
		break;
	case DATA_MANAGER_USER_NOT_REGISTER_ERROR:
		re_type = RESPONSE_TYPE_USER_NOT_EXISTED;
		break;
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,

			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 用户在线状态保持，无参数
 */
static ExecuteQueue *
keep_online_state(euint64 online_id, EventList *args, int sock)
{
	int status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, keep_online_state, "用户在线状态保持。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	status	= data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}

	status = data_manager_flush_keep_state(data_manager, online_id);
	if (status == DATA_MANAGER_USER_NOT_LOGON)
		re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
	else if (status == DATA_MANAGER_SUCCESS)
		re_type = RESPONSE_TYPE_SUCCESS;
	else
		re_type = RESPONSE_TYPE_ERROR;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 移除事件组，参数：
 * 1. 事件组 GroupID
 */
static ExecuteQueue *
remove_group(euint64 online_id, EventList *args, int sock)
{
	euint32 groud_id;
	int	status;
	re_type = RESPONSE_TYPE_ERROR;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, remove_group, "移除事件组。");
#endif

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	groud_id = (euint32)EN_GET_D(args, euint64);
	//
	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_remove_group(data_manager, user_id, groud_id);

	switch (status) {
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_PERMISSION_DENIED:
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
		break;
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 从事件组中移除某位成员，参数：
 * 1. 事件组 GroupID，2. 用户 UserID
 */
static ExecuteQueue *
remove_member_from_group(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id, will_remove_uid;
	int	status;
	re_type = RESPONSE_TYPE_ERROR;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, remove_member_from_group,
		    "从事件组中移除某位成员。");
#endif

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	will_remove_uid = (euint32)EN_GET_NEXT(args, euint64);
	//
	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_remove_member_from_group(
		 data_manager, user_id, group_id, will_remove_uid);
	switch (status) {
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_PERMISSION_DENIED:
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
		break;
	case DATA_MANAGER_USER_NOT_BELONG_GROUP:
		re_type = RESPONSE_TYPE_USER_NOT_BELONG_GROUP;
		break;
	case DATA_MANAGER_USER_NOT_REGISTER_ERROR:
		re_type = RESPONSE_TYPE_USER_NOT_EXISTED;
		break;
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 从事件组中移除一条事件，参数：
 * 1. 事件组 GroupID，2. 事件条目 EventID
 */
static ExecuteQueue *
remove_event_from_group(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id, event_id;
	int	status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, remove_event_from_group,
		    "从事件组中移除一条事件。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	args	 = EN_GET_NEXT(args, EventList *);
	if (!args || !event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	event_id = (euint32)EN_GET_D(args, euint64);
	//
	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}

	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_remove_event_from_group(data_manager, user_id,
						       group_id, event_id);
	switch (status) {
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_CAN_NOT_WRITE:
		re_type = RESPONSE_TYPE_GROUP_CAN_NOT_WRITE;
		break;
	case DATA_MANAGER_EVENT_ITEM_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_EVENT_ITEM_NOT_EXIST;
		break;
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * 用户自行退出某事件组，参数：
 * 1. 事件组 GroupID
 */
static ExecuteQueue *
user_quit_from_group(euint64 online_id, EventList *args, int sock)
{
	euint32 group_id;
	int	status;
	re_type = RESPONSE_TYPE_ERROR;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_quit_from_group,
		    "用户自行退出某事件组。");
#endif

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);
	//
	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status = data_manager_handle_user_quit_from_group(data_manager, user_id,
							  group_id);
	switch (status) {
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_USER_NOT_BELONG_GROUP:
		re_type = RESPONSE_TYPE_USER_NOT_BELONG_GROUP;
		break;
	case DATA_MANAGER_USER_NOT_REGISTER_ERROR:
		re_type = RESPONSE_TYPE_USER_NOT_EXISTED;
		break;
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	case DATA_MANAGER_CAN_NOT_QUIT_DEFAULT_GROUP:
		re_type = RESPONSE_TYPE_CAN_NOT_QUIT_DEFAULT_GROUP;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * @brief 拉取用户的所有事件。（以后可以设计拉取范围），暂无参数
 */
static ExecuteQueue *
user_fetch_all_event(euint64 online_id, EventList *args, int sock)
{
	EventList *response_list = NULL;
	int	   status;
	//

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_fetch_all_event, "拉取用户所有事件。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	status	= data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	response_list =
		data_manager_user_fetch_all_event(data_manager, user_id);
	if (response_list)
		re_type = RESPONSE_TYPE_SUCCESS;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (response_list) {
		event_list_add_data(send_list, response_list, EVENT_TYPE_LIST,
				    event_object_unref);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

/**
 * @brief 拉取用户加入的所有事件组信息
 */
static ExecuteQueue *
user_fetch_all_group_info(euint64 online_id, EventList *args, int sock)
{
	EventList *response_list = NULL;
	int	   status;
	//

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_fetch_all_group_info,
		    "拉取用户加入的所有组信息。");
#endif

	re_type = RESPONSE_TYPE_ERROR;
	status	= data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	response_list =
		data_manager_user_fetch_all_group_info(data_manager, user_id);
	if (response_list)
		re_type = RESPONSE_TYPE_SUCCESS;

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (response_list) {
		event_list_add_data(send_list, response_list, EVENT_TYPE_LIST,
				    event_object_unref);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

ExecuteQueue *
user_join_group(euint64 online_id, EventList *args, int sock)
{
	EventString *group_name = NULL;
	euint32	     group_id;
	int	     status;

#if (EVENT_DEBUG)
	event_debug(EventExecuter, user_join_group, "用户加入事件组。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}

	user_id = data_manager_get_uid_from_oid(data_manager, online_id);
	status	= data_manager_user_join_group(data_manager, user_id, group_id);
	group_name = data_manager_dup_user_joined_group_name(data_manager);
	switch (status) {
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_PERMISSION_DENIED:
		re_type = RESPONSE_TYPE_GROUP_CAN_NOT_JOIN;
		break;
	case DATA_MANAGER_USER_EXISTED_IN_GROUP:
		re_type = RESPONSE_TYPE_USER_EXISTED_IN_GROUP;
		break;
	case DATA_MANAGER_SUCCESS:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	default:
		re_type = RESPONSE_TYPE_ERROR;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (group_name) {
		event_list_add_data(send_list, group_name, EVENT_TYPE_STRING,
				    event_object_unref);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

static ExecuteQueue *
group_fetch_all_member_info(euint64 online_id, EventList *args, int sock)
{
	EventList *response_list = NULL;
	euint32	   group_id;
	int	   status;
	//

#if (EVENT_DEBUG)
	event_debug(EventExecuter, group_fetch_all_member_info,
		    "拉取组内所有用户的信息。");
#endif

	re_type = RESPONSE_TYPE_ERROR;

	if (!event_list_verify_node_type(args, EVENT_TYPE_UINT32))
		goto return_with_node;
	group_id = (euint32)EN_GET_D(args, euint64);

	status = data_manager_verify_logon_state(data_manager, online_id);
	if (status != 0) {
		if (status == 2)
			re_type = RESPONSE_TYPE_NEED_VERIFICATION_CODE;
		else if (status == 1)
			re_type = RESPONSE_TYPE_NEED_LOGON_AGAIN;
		goto return_with_node;
	}
	user_id	      = data_manager_get_uid_from_oid(data_manager, online_id);
	response_list = data_manager_fetch_all_memeber_info(data_manager,
							    user_id, group_id);

	switch (data_manager_get_result(data_manager)) {
	case DATA_MANAGER_NULL_OBJECT_ERROR:
		re_type = RESPONSE_TYPE_SYSTEM_BUGS;
		break;
	case DATA_MANAGER_GROUP_NOT_EXIST_ERROR:
		re_type = RESPONSE_TYPE_GROUP_NOT_EXIST_ERROR;
		break;
	case DATA_MANAGER_GROUP_PERMISSION_DENIED:
		re_type = RESPONSE_TYPE_GROUP_PERMISSION_DENIED;
		break;
	default:
		re_type = RESPONSE_TYPE_SUCCESS;
		break;
	}

return_with_node:
	send_node = execute_queue_new();
	send_list = event_list_new();
	event_list_add_data(send_list, EPTR((euint64)NETWORK_RET_TYPE_NORMAL),
			    EVENT_TYPE_INT32, NULL);
	event_list_add_data(send_list, EPTR((euint64)re_type), EVENT_TYPE_INT32,
			    NULL);
	if (response_list) {
		event_list_add_data(send_list, response_list, EVENT_TYPE_LIST,
				    event_object_unref);
	}
	execute_queue_set(send_node, sock, send_list);
	return send_node;
}

typedef ExecuteQueue *(*ExecuteFunc)(euint64 online_id, EventList *args,
				     int sock);

static ExecuteFunc exe_func[EXECUTE_TYPE_END] = {
	close_connect, // 0
	register_method,
	user_logon,
	user_logon_with_verification_code,
	modify_password,
	modify_user_name, // 5
	modify_group_name,
	modify_event_item,
	modify_group_can_write_flag,
	modify_member_can_write_flag,
	modify_group_can_join_flag, // 10
	create_group,
	create_event,
	add_user_to_group,
	remove_group,
	remove_member_from_group, // 15
	remove_event_from_group,
	user_quit_from_group,
	keep_online_state,
	user_fetch_all_event,
	user_fetch_all_group_info, // 20
	user_join_group,
	group_fetch_all_member_info,
};

/**
 * 解析一个 ClientRequests 节点
 * 该节点包含：
 * 1) sock
 * 2) 指令集 EventList: 包含数据节点类型，数据链下个节点
 * 提示：不要在此释放 list 节点！
 */
static void
execute_with_list(ExecuteQueue *q_node)
{
	ExecuteQueue *send_node;
	EventList    *command, *args = NULL;
	euint64	      online_id;
	int	      sock;
	ExecuteType   cmd_type = EXECUTE_TYPE_NONE;
	//
	command = execute_queue_get_command(q_node);
	sock	= execute_queue_get_sock(q_node);

	if (!command ||
	    !event_list_verify_node_type(command, EVENT_TYPE_UINT64))
		goto execute_with_error;
	online_id = EN_GET_D(command, euint64);
	command	  = EN_GET_NEXT(command, EventList *);
	if (!command || !event_list_verify_node_type(command, EVENT_TYPE_INT32))
		goto execute_with_error;
	cmd_type = (ExecuteType)EN_GET_D(command, euint64);
	command	 = EN_GET_NEXT(command, EventList *);
	if (!command || !event_list_verify_node_type(command, EVENT_TYPE_LIST))
		goto execute_with_error;
	args = EN_GET_D(command, EventList *);

execute_with_error:
	if (cmd_type >= EXECUTE_TYPE_END || cmd_type < EXECUTE_TYPE_NONE)
		cmd_type = EXECUTE_TYPE_NONE;
	event_debug(EventExecuter, execute_with_list, "执行任务类型: %d",
		    cmd_type);
	/* 执行准备好的方法 */
	send_node = exe_func[cmd_type](online_id, args, sock);
	network_object_add_task(net_obj, send_node);
}

void
event_executer_run_node(EventExecuter *self, ExecuteQueue *q_node)
{
	execute_with_list(q_node);
	event_object_unref(q_node);
}
